package com.haozhen;

import com.alibaba.druid.pool.DruidDataSource;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;

/**
 * @author haozhen
 * @email haozh@ync1.com
 * @date 2020/10/24  0:55=
 * zk 客户端 对zk节点数据进行动态监听，切换数据源
 */
public class DataSourceClient  implements IZkDataListener {

    private ZkClient zkClient;

    private DruidDataSource dataSource;

    private DataSourceLinkInfo dataSourceLinkInfo;

    public  DataSourceClient initZkClient(){
        zkClient = new ZkClient(ZkInfo.zkServer);
        zkClient.setZkSerializer(new SerializableSerializer());
        return this;
    }

    public void  getDataSource(){
       zkClient.readData(ZkInfo.zkNode);
    }

    public void  initDataSource(){
        dataSourceLinkInfo = zkClient.readData(ZkInfo.zkNode);
        if(Objects.isNull(dataSourceLinkInfo)){
            System.out.println("数据库配置信息有误");
            return;
        }
        if(null!=dataSourceLinkInfo.getUrl() && ""!=dataSourceLinkInfo.getUrl()){//简单校验
            DruidProperties druidProperties = new DruidProperties(dataSourceLinkInfo);
            dataSource = new DruidDataSource();
            druidProperties.dataSource(dataSource);
        }else{
            System.out.println("数据库配置信息有误");
        }
    }

    public void destoryDataSource(){
        this.dataSource.shrink(true,this.dataSource.isKeepAlive());
        if (this.dataSource.isRemoveAbandoned()) {
            this.dataSource.removeAbandoned();
        }
        this.dataSourceLinkInfo = null;
    }

    public void testDataSource(){
        if(this.dataSource==null){
            System.out.println("数据连接池未初始化成功");
            ;return;
        }
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            dataSource.init();
            connection = dataSource.getConnection();
            String sql = "select * from sys_user";
            preparedStatement = connection.prepareStatement(sql);

            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                String username = resultSet.getString("username");
                String sex = resultSet.getString("sex");
                String address = resultSet.getString("address");
                System.out.println(username +"\t" + sex + "\t" + address);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (preparedStatement != null) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void changeListerner(){
        zkClient.subscribeDataChanges(ZkInfo.zkNode,this);
    }

    @Override
    public void handleDataChange(String s, Object o) throws Exception {
        System.out.println("节点："+s+"发生变化\t"+"数据现在是"+o);
        //销毁之前的连接
        this.destoryDataSource();
        this.testDataSource();
        //创建新的连接
        this.initDataSource();
        this.testDataSource();
    }

    @Override
    public void handleDataDeleted(String s) throws Exception {
        System.out.println("节点："+s+"被删除");
        this.destoryDataSource();
    }
}
